feat(agents): config-driven local-model backend for CE copilots#365
Merged
Conversation
The Studies/Publish/Abby copilots run on the Claude Agent SDK and were "EE-only" purely because the claude CLI needs a funded Anthropic key. The agent loop (MCP tools, can_use_tool approval gating, Reverb streaming, HIGHSEC lockdown) is model-agnostic, so CE support is a runtime config decision, not a code fork. - config: AGENT_PROVIDER + AGENT_LOCAL_* settings and resolve_agent_provider() - service._options(): for the local provider, swap in the local model/effort and inject ANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKEN via ClaudeAgentOptions.env (redirects the CLI to a proxy, no change to tool/approval/streaming logic); withdraw approval-gated WRITE tools when local actions are disabled - profiles: optional per-profile provider override (inherits global) - router + AbbyAgentController: surface provider + actions_enabled so the dock hides action affordances on a reads-only CE deployment - frontend: store the flags; AbbyCopilotPanel shows a reads-only note - docker: claude-code-router sidecar gated behind profiles:["ce"] (inert in the EE stack), non-root per HIGHSEC 4.1 Defaults preserve EE behavior end-to-end (anthropic provider, Opus, actions on). Verified with the SDK client mocked (no GPU/credit): Python 41, PHP 5, frontend 9; mypy/Pint/PHPStan/tsc/vite build clean; compose valid with the sidecar correctly inert outside --profile ce. The proxy's live boot needs an operator box with Ollama + the model pulled (steps in the devlog). Co-Authored-By: claude-flow <ruv@ruv.net>
Six agent-provider vars for the EE/CE switch, defaults preserving EE behavior.
They already work via docker-compose ${VAR:-default} interpolation; this just
makes them discoverable in the example env.
Co-Authored-By: claude-flow <ruv@ruv.net>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The Studies/Publish/Abby copilots run on the Claude Agent SDK in
python-ai(ai/app/agents/service.py), which drives theclaudeCLI against the Anthropic cloud API. Nothing gated them by edition — they were "EE-only" purely because the CLI needs a fundedANTHROPIC_API_KEY. CE deployments need the same omnipresent Abby without a cloud dependency.The agent loop (9-tool in-process MCP server,
can_use_toolapproval gating, Reverb streaming, HIGHSEC lockdown) is model-agnostic — it lives in our code, not Anthropic's. So CE support is a runtime config decision, not a code fork: change only where the CLI sends requests and which tools are auto-enabled.What changed
ai/app/config.py):AGENT_PROVIDER+AGENT_LOCAL_*settings andresolve_agent_provider()→ResolvedAgentProvider._options()): for the local provider, swap in the local model/effort and injectANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKENviaClaudeAgentOptions.env(redirects the CLI subprocess to a proxy — no change to tool/approval/streaming logic); withdraw approval-gated WRITE tools when local actions are disabled.provideroverride (inherits the global).AbbyAgentController: surfaceprovider+actions_enabledso the dock hides action affordances on a reads-only CE deployment.AbbyCopilotPanelshows a reads-only note when actions are disabled.claude-code-routersidecar gated behindprofiles: ["ce"](inert in the EE stack), non-root per HIGHSEC 4.1.EE / CE matrix
anthropic)local, actions off)local, actions on)Defaults preserve EE behavior end-to-end (anthropic provider, Opus, actions on). The first service test asserts the cloud model + gated writes when the provider defaults to
anthropic.Verification
Verified with the SDK client mocked (no GPU/credit): Python 41, PHP 5, frontend 9;
mypy/Pint/PHPStan/tsc/vite buildclean;docker compose configvalid with the sidecar correctly inert outside--profile ce. Deployed to prod — EE path unchanged (/health200, resolver reportsanthropic/claude-opus-4-7).NOT verified here (operator action)
The
claude-routerimage build + live boot + a real local-model turn need a host with Ollama andAGENT_LOCAL_MODELpulled (+ GPU). Operator smoke steps are indocs/lineage/modules/abby-ai/local-model-agent-backend-ce.md.🤖 Generated with claude-flow